/*
 * Copyright (C), 2002-2016, 苏宁易购电子商务有限公司
 * FileName: ModelTaskServiceImpl.java
 * Author:   13075787
 * Date:     2016年7月8日 上午9:09:20
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.sawp.service.impl.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.suning.nsfuaa.common.NsfuaaResult;
import com.suning.nsfuaa.employee.EmployeeService;
import com.suning.nsfuaa.employee.dto.EmpListOfOrgPos;
import com.suning.nsfuaa.employee.dto.EmployeeInfo;
import com.suning.rsf.consumer.ServiceLocator;
import com.suning.sawp.constants.CacheKeyConstants;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.LoggerConstants;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.storeman.Category;
import com.suning.sawp.intf.model.ModelConstant;
import com.suning.sawp.intf.model.ModelTaskAssignCategoryBean;
import com.suning.sawp.intf.model.ModelTaskAssignDetailsBean;
import com.suning.sawp.intf.model.ModelTaskHomeFlagVo;
import com.suning.sawp.intf.model.SubmitAssignReq;
import com.suning.sawp.intf.model.TaskBranchVo;
import com.suning.sawp.intf.model.TaskCateVo;
import com.suning.sawp.intf.model.TaskInfoVo;
import com.suning.sawp.intf.storeman.StoreValidResult;
import com.suning.sawp.service.util.GsonUtils;
import com.suning.sawp.service.util.RedisCacheUtils;
import com.suning.sawp.service.util.SCMConfigUtil;
import com.suning.vgs.follow.remote.intf.StoreManRemoteService;

/**
 * 样机管理 <br>
 * 任务管理
 *
 * @author 13075787
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service("modelTaskService")
public class ModelTaskServiceImpl {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConstants.SAWP_SERVICE);

    private EmployeeService employeeService = ServiceLocator.getService(EmployeeService.class, "");

    @Autowired
    ModelTaskDaoServiceImpl modelTaskDaoService;

    @Autowired
    ModelProbDaoServiceImpl modelProbDaoService;

    @Autowired
    StoreManRemoteService storeManRemoteService;

    @Resource
    RedisCacheUtils cacheUtils;
    
    @Resource
    StaffInfoServiceImpl staffInfoServiceImpl;

    /**
     * 功能描述: <br>
     * 查询首页各个任务是否存在的标记
     *
     * @param storeMan
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ReturnMsg<ModelTaskHomeFlagVo> queryTaskHomeFlag(StoreManDto storeMan) {
        ReturnMsg<ModelTaskHomeFlagVo> result = new ReturnMsg<ModelTaskHomeFlagVo>();
        ModelTaskHomeFlagVo data = new ModelTaskHomeFlagVo();
        String staffId = storeMan.getStaffId();
        // 确认是否从缓存中获取数据
        String cackeKey = String.format(CacheKeyConstants.MODEL_TASK_HOME, staffId);
        int cacheTime = this.getHomeFlagCacheTime();
        if (cacheTime > ModelConstant.NUM_ZERO) {
            ModelTaskHomeFlagVo cacheData = cacheUtils.get(cackeKey, ModelTaskHomeFlagVo.class);
            if (null != cacheData) {
                result.setData(cacheData);
                return result;
            }
        }
        boolean checkTaskFlag = false;
        boolean clusterTaskFlag = false;
        // 是否有盘点任务
        checkTaskFlag = this.queryTaskFlag(storeMan, null);
        // 是否有簇维护任务，废弃簇维护任务。12061818
//        clusterTaskFlag = this.queryTaskFlag(storeMan, ModelConstant.TASK_TYPE_CLUSTER);
        data.setCheckTaskFlag(checkTaskFlag ? ModelTaskHomeFlagVo.EXIST_FLAG : ModelTaskHomeFlagVo.NO_FLAG);
        data.setClusterTaskFlag(clusterTaskFlag ? ModelTaskHomeFlagVo.EXIST_FLAG : ModelTaskHomeFlagVo.NO_FLAG);
        // 是否有需要审核或者异常处理
        data.setProblemAuditFlag(modelProbDaoService.queryProbAuditFlag(staffId) ? ModelTaskHomeFlagVo.EXIST_FLAG
                : ModelTaskHomeFlagVo.NO_FLAG);
        data.setProblemHandlingFlag(modelProbDaoService.queryProbHandlingFlag(staffId) ? ModelTaskHomeFlagVo.EXIST_FLAG
                : ModelTaskHomeFlagVo.NO_FLAG);
        // 对首页任务标识进行缓存，默认时间设置为0不缓存
        if (cacheTime > ModelConstant.NUM_ZERO) {
            cacheUtils.setex(cackeKey, cacheTime, data);
        }
        result.setData(data);
        return result;
    }

    /**
     * 首页任务标识缓存时间
     */
    private int getHomeFlagCacheTime() {
        String expireTime = SCMConfigUtil.getConfig(ConfigConstants.MODEL_TASK_HOME_CACHE_TIME, String.valueOf("0"));
        int cacheExpireTime = Integer.valueOf(expireTime);
        return cacheExpireTime;
    }

    /**
     * 查询除去分配品类的任务是否存在
     */
    private boolean queryTaskFlag(StoreManDto storeMan, Integer taskType) {
        boolean result = false;
        String storeCode = storeMan.getStoreCode();
        String staffId = storeMan.getStaffId();
        String positionId = storeMan.getPositionId();
        // 先查询是否存在执行任务
        result = modelTaskDaoService.queryTaskExistFlag(storeCode, staffId, taskType, null);
        // 上述任务不存在则查询分配类的任务
        if (!result) {
            List<String> cateCodes = null;
            if (ClerkConstants.SALE_GUIDE.equals(positionId)) {
                cateCodes = this.toCateCodeList(storeMan.getCategories());
            }
            result = modelTaskDaoService.queryAssigTaskExistFlag(storeCode, taskType, cateCodes, staffId);
        }
        // 上述任务还不存在的话，若是店长(正副)则查下是否存在无挂靠督导的类目
        if (!result) {
            if (ClerkConstants.STORE_KEEPER.equals(positionId)
                    || ClerkConstants.DEPUTY_STORE_KEEPER.equals(positionId)) {
                List<String> cates = this.queryNoCateCodes(storeCode, taskType, null);
                if (CollectionUtils.isNotEmpty(cates)) {
                    result = true;
                }
            }
        }
        return result;
    }

    /**
     * 提出品类编码
     */
    private List<String> toCateCodeList(List<Category> categorys) {
        List<String> result = null;
        if (CollectionUtils.isNotEmpty(categorys)) {
            result = new ArrayList<String>();
            for (Category category : categorys) {
                result.add(category.getCategoryCode());
            }
        }
        return result;
    }

    /**
     * 查询出未挂靠督导且未分配的品类编码列表
     */
    private List<String> queryNoCateCodes(String storeCode, Integer taskType, Long taskId) {
        List<String> result = new ArrayList<String>();
        // 查询出该门店下所有品类（除去已分配的）
        List<String> cateCodes = modelTaskDaoService.queryTaskCates(storeCode, taskType, null);
        if (CollectionUtils.isNotEmpty(cateCodes)) {
            Set<String> set = new HashSet<String>();
            set.addAll(cateCodes);
            // 查询rsf接口，筛选出未挂靠督导的品类
            List<StoreValidResult> validList  = staffInfoServiceImpl.validHasGuide(storeCode, cateCodes);
//            List<StoreGuideValidResult> validList = storeManRemoteService.validHasGuide(storeCode, cateCodes);
            if (CollectionUtils.isNotEmpty(validList)) {
                for (StoreValidResult storeGuideValidResult : validList) {
                    if (!storeGuideValidResult.getGuideExist()) {
                        if (set.contains(storeGuideValidResult.getCateCode())) {
                            // 该品类为任务中且无挂靠督导的品类
                            result.add(storeGuideValidResult.getCateCode());
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询任务列表
     *
     * @param storeMan
     * @param taskType
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ReturnMsg<List<TaskInfoVo>> queryTaskList(StoreManDto storeMan, Integer taskType) {
        ReturnMsg<List<TaskInfoVo>> result = new ReturnMsg<List<TaskInfoVo>>();
        List<TaskInfoVo> taskResult = new ArrayList<TaskInfoVo>();
        String positionId = storeMan.getPositionId();
        String storeCode = storeMan.getStoreCode();
        String staffId = storeMan.getStaffId();
        List<String> cateCodes = null;
        if (ClerkConstants.SALE_GUIDE.equals(positionId)) {
            cateCodes = this.toCateCodeList(storeMan.getCategories());
        }
        // 首先查询出该员工所有分配品牌+执行的任务
        List<TaskInfoVo> taskList = modelTaskDaoService.queryTaskInfoList(storeCode, taskType, staffId, cateCodes);
        // 是店长+副店长 首先查询这个门店无挂靠督导的品类 角色是店长(正副)则要查下需要分配品类任务
        List<TaskInfoVo> cateTaskList = new ArrayList<TaskInfoVo>();
        if (ClerkConstants.STORE_KEEPER.equals(positionId) || ClerkConstants.DEPUTY_STORE_KEEPER.equals(positionId)) {
            List<String> noCateCodes = this.queryNoCateCodes(storeCode, taskType, null);
            if (CollectionUtils.isNotEmpty(noCateCodes)) {
                cateTaskList = modelTaskDaoService.queryTaskCateInfoList(storeCode, taskType, noCateCodes, null);
            }
        }
        taskResult.addAll(cateTaskList);
        taskResult.addAll(taskList);
        result.setData(taskResult);
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询可分配的人员列表
     *
     * @param storeMan
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ReturnMsg<List<EmployeeInfo>> queryAssignedEmployee(StoreManDto storeMan) {
        ReturnMsg<List<EmployeeInfo>> result = new ReturnMsg<List<EmployeeInfo>>();
        List<EmployeeInfo> data = new ArrayList<EmployeeInfo>();
        // 正店长、副店长、督导、营业员、促销员
        String[] positionIds = { ClerkConstants.STORE_KEEPER, ClerkConstants.DEPUTY_STORE_KEEPER,
                ClerkConstants.SALE_GUIDE, ClerkConstants.SALES_CLERK, ClerkConstants.SALES_PROMOTION };
        EmpListOfOrgPos orgPos = employeeService.getEmpListOfOrgPos(storeMan.getStoreCode(),
                StringUtils.join(positionIds, ","));
        if (null != orgPos && NsfuaaResult.SUCCESS == orgPos.getStatus()) {
            data = orgPos.getEmpList();
        }
        result.setData(data);
        return result;
    }

    /**
     * 功能描述: <br>
     * 查询某个任务可分配的品牌列表
     *
     * @param storeMan
     * @param taskId
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ReturnMsg<List<TaskCateVo>> queryAssignedBranchs(StoreManDto storeMan, Long taskId) {
        ReturnMsg<List<TaskCateVo>> result = new ReturnMsg<List<TaskCateVo>>();
        result.setRetFlag(ReturnMsg.SUCCESS);
        List<String> cateCodes = null;
        String positionId = storeMan.getPositionId();
        if (ClerkConstants.SALE_GUIDE.equals(positionId)) {
            cateCodes = this.toCateCodeList(storeMan.getCategories());
        }
        if (null != taskId) {
            List<TaskInfoVo> list = modelTaskDaoService.queryAssignBranchForTask(taskId, storeMan.getStoreCode(), null,
                    cateCodes, storeMan.getStaffId());
            if (CollectionUtils.isNotEmpty(list)) {
                TaskInfoVo taskInfoVo = list.get(ModelConstant.NUM_ZERO);
                if (null != taskInfoVo) {
                    result.setData(taskInfoVo.getCates());
                }
            }
        } else {
            // 入参缺失
            result.setError(ModelConstant.MODEL_ERROR_NO_PARAM,
                    "taskId" + ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_PARAM));
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 为店长(正副)查询未分配的品类列表(指定任务)
     * 
     * @param storeMan
     * @param taskId
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ReturnMsg<List<TaskCateVo>> queryAssignedCates(StoreManDto storeMan, Long taskId) {
        ReturnMsg<List<TaskCateVo>> result = new ReturnMsg<List<TaskCateVo>>();
        result.setRetFlag(ReturnMsg.SUCCESS);
        String positionId = storeMan.getPositionId();
        String storeCode = storeMan.getStoreCode();
        // 参数缺失-直接返回
        if (null == taskId) {
            // 入参缺失
            result.setError(ModelConstant.MODEL_ERROR_NO_PARAM,
                    "taskId" + ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_PARAM));
            return result;
        }
        if (ClerkConstants.STORE_KEEPER.equals(positionId) || ClerkConstants.DEPUTY_STORE_KEEPER.equals(positionId)) {
            List<String> noCateCodes = this.queryNoCateCodes(storeCode, null, taskId);
            if (CollectionUtils.isNotEmpty(noCateCodes)) {
                List<TaskInfoVo> list = modelTaskDaoService.queryTaskCateInfoList(storeCode, null, noCateCodes, taskId);
                if (CollectionUtils.isNotEmpty(list)) {
                    // 获取第一个
                    TaskInfoVo taskInfoVo = list.get(ModelConstant.NUM_ZERO);
                    if (null != taskInfoVo) {
                        result.setData(taskInfoVo.getCates());
                    }
                }
            }
        } else {
            result.setError(ModelConstant.MODEL_ERROR_NO_AUTH,
                    storeMan.getStaffId() + ModelConstant.getErrorValue(ModelConstant.MODEL_ERROR_NO_AUTH));
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 分配品类提交
     *
     * @param storeMan
     * @param submitAssignReqs
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("rawtypes")
    public ReturnMsg submitAssignCateTask(StoreManDto storeMan, List<SubmitAssignReq> submitAssignReqs) {
        ReturnMsg result = new ReturnMsg();
        result.setRetFlag(ReturnMsg.SUCCESS);
        if (CollectionUtils.isNotEmpty(submitAssignReqs)) {
            // 将数据库数据转为数据结构
            List<ModelTaskAssignCategoryBean> assignCates = new ArrayList<ModelTaskAssignCategoryBean>();
            for (SubmitAssignReq submitAssignReq : submitAssignReqs) {
                List<TaskCateVo> cateList = submitAssignReq.getCates();
                if (CollectionUtils.isNotEmpty(cateList)) {
                    for (TaskCateVo taskCateVo : cateList) {
                        ModelTaskAssignCategoryBean taskAssignCategoryBean = new ModelTaskAssignCategoryBean();
                        taskAssignCategoryBean.setTaskId(Long.valueOf(submitAssignReq.getTaskId()));
                        // 检查该工号是否是有员工信息 - 可降级
                        taskAssignCategoryBean.setAcceptStaff(submitAssignReq.getStaffId());
                        taskAssignCategoryBean.setAssignStaff(storeMan.getStaffId());
                        taskAssignCategoryBean.setStoreCode(storeMan.getStoreCode());
                        taskAssignCategoryBean.setCateCode(taskCateVo.getCateCode());
                        taskAssignCategoryBean.setCateName(taskCateVo.getCateName());
                        assignCates.add(taskAssignCategoryBean);
                    }
                } else {
                    // 无指定类目
                    LOGGER.error("样机管理-分配品类-入参缺失:" + GsonUtils.toJson(submitAssignReq));
                }
            }
            modelTaskDaoService.upsertAssignCateTask(assignCates);
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 分配品牌提交
     *
     * @param storeMan
     * @param submitAssignReqs
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("rawtypes")
    public ReturnMsg submitAssignBrandTask(StoreManDto storeMan, List<SubmitAssignReq> submitAssignReqs) {
        ReturnMsg result = new ReturnMsg();
        result.setRetFlag(ReturnMsg.SUCCESS);
        if (CollectionUtils.isNotEmpty(submitAssignReqs)) {
            // 将数据库数据转为数据结构
            List<ModelTaskAssignDetailsBean> assignBrands = new ArrayList<ModelTaskAssignDetailsBean>();
            for (SubmitAssignReq submitAssignReq : submitAssignReqs) {
                List<TaskCateVo> cateList = submitAssignReq.getCates();
                if (CollectionUtils.isNotEmpty(cateList)) {
                    for (TaskCateVo taskCateVo : cateList) {
                        List<TaskBranchVo> brandList = taskCateVo.getBranchs();
                        if (CollectionUtils.isNotEmpty(brandList)) {
                            for (TaskBranchVo taskBranchVo : brandList) {
                                ModelTaskAssignDetailsBean taskAssignDetailsBean = new ModelTaskAssignDetailsBean();
                                taskAssignDetailsBean.setTaskId(Long.valueOf(submitAssignReq.getTaskId()));
                                taskAssignDetailsBean.setStoreCode(storeMan.getStoreCode());
                                // 检查该工号是否是有员工信息 - 可降级
                                taskAssignDetailsBean.setAcceptStaff(submitAssignReq.getStaffId());
                                taskAssignDetailsBean.setAssignStaff(storeMan.getStaffId());
                                taskAssignDetailsBean.setAssignStatus(ModelConstant.TASK_ASSIGN_STATUS_DONE);
                                taskAssignDetailsBean.setCateCode(taskCateVo.getCateCode());
                                taskAssignDetailsBean.setBranch9code(taskBranchVo.getBranch9Code());
                                assignBrands.add(taskAssignDetailsBean);
                            }
                        } else {
                            // 无指定品牌
                            LOGGER.error("样机管理-分配品牌-入参缺失:" + GsonUtils.toJson(submitAssignReq) + "员工信息:"
                                    + storeMan.toString());
                        }
                    }
                } else {
                    // 无指定类目
                    LOGGER.error("样机管理-分配品牌-入参缺失:" + GsonUtils.toJson(submitAssignReq) + "员工信息:" + storeMan.toString());
                }
            }
            modelTaskDaoService.updateAssignBrandTask(assignBrands);
        }
        return result;
    }

}
